package demo1;

import org.junit.Test;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.List;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author lilingzhi
 * @since 2022/12/21 14:22
 */
public class Demo1 {


    /**
     * predicate
     *  谓词语句
     *  negate | and | or
     */


    /**
     * 函数复合
     * andThen 根据先后顺序·执行
     * compose 先执行参数
     */
    @Test
    public void test1() {
        Function<Integer, Integer> f = x -> x + 1;
        Function<Integer, Integer> g = x -> x * 2;
        Function<Integer, Integer> h = f.andThen(g); // <=> y = g(f(x))
        Integer apply = h.apply(2);
        System.out.println(apply);

        Function<Integer, Integer> h1 = f.compose(g); // <=> y = f(g(x))
        System.out.println(h1.apply(2));
    }


    /**
     * andThen 用法 ,根据先后顺序 , 将前者的结果作为后者的参数
     */
    @Test
    public void test2() {
        Function<Integer, String> iToHex = i -> "'" + Integer.toHexString(i) + "'";
        Function<Integer, String> itoUpperHex = iToHex.andThen(String::toUpperCase);
        String apply1 = iToHex.apply(111);
        System.out.println(apply1);
        String apply = itoUpperHex.apply(111);
        System.out.println(apply);
    }


    @Test
    public void test3() {
        UnaryOperator<String> quote = s -> "'" + s + "'";
        Function<Integer, String> itoCompose = quote.compose(Integer::toHexString);
        String apply = itoCompose.apply(111);
        System.out.println(apply);
    }


    /**
     * y = x + 3  对其积分处理操作
     */
    @Test
    public void test4() {
        // y = x + 3; 函数
        DoubleFunction<Double> fun = x -> x + 3;

        double integrate = integrate(fun, 1D, 3D);
        System.out.println(integrate);

    }

    /**
     *
     */
    private double integrate(DoubleFunction<Double> fun, Double i, Double j) {
        return (fun.apply(i) + fun.apply(j)) / 2 * (j - i);
    }

    /**
     * 对函数进行求导处理
     */
    @Test
    public void test5() {
        Double apply = new DerivedFunction(new UnaryOperator<Double>() {
            @Override
            public Double apply(Double aDouble) {
                return aDouble * aDouble + 3;
            }
        }).apply(6d);
        System.out.println(apply);
    }


    // 流的内部迭代 和 流的 外部迭代


    /**
     * 流的扁平化处理
     */
    @Test
    public void flatMapTest() {
        // 针对 ["HELLO","WORLD"] 进行扁平化处理
        List<String> list = Arrays.asList("HELLO", "WORLD");
        List<String> collect = list.stream().map(str -> str.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());
//        collect.forEach(System.out::println);

        List<List<String>> lists = Arrays.asList(Arrays.asList("mes", "aa", "DDD"), Arrays.asList("Hello", "world"));

        List<String[]> collect1 = lists.stream().flatMap(i ->
                i.stream().map(str -> str.split(""))
        ).distinct().collect(Collectors.toList());

        collect1.forEach(listss -> {
            Arrays.stream(listss).forEach(System.out::println);
        });
    }

    /**
     * [1,2,3] 和 [4,5] ===> [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
     */
    @Test
    public void flatMapTest2() {
        List<Integer> listNum1 = Arrays.asList(1, 2, 3);
        List<Integer> listNum2 = Arrays.asList(4, 5);
        List<List<Integer>> collect = listNum1.stream().flatMap(nums1 -> listNum2.stream().map(j -> Arrays.asList(nums1, j))).collect(Collectors.toList());
        collect.forEach(System.out::println);
    }


//    @Test
//    public void test1() {
//        FormattingConversionService conversionService = new FormattingConversionService();
//        // 注册员负责添加格式化器以支持Date系列的转换
//        new DateTimeFormatterRegistrar().registerFormatters((FormatterRegistry) conversionService);
//        // 1、普通使用(API方式)
//        LocalDateTime now = LocalDateTime.now();
//        System.out.println("当前时间：" + now);
//        System.out.println("LocalDateTime转为LocalDate：" + conversionService.convert(now, LocalDate.class));
//        System.out.println("LocalDateTime转为LocalTime：" + conversionService.convert(now, LocalTime.class));      // 时间戳转Instant     long currMills = System.currentTimeMillis();     System.out.println("当前时间戳：" + currMills);     System.out.println("时间戳转Instant：" + conversionService.convert(currMills, Instant.class)); }
// }
}